let pomelo = require("pomelo");
let logger = require("pomelo-logger").getLogger(__filename);
let BasePlayer = require("../base/yuanbaoPlayer");
let util = require("util");
let MahjongUtils = require("../../mahjong/utils/MahjongUtils");
let ZhuojiGameConstant = require("../../mahjong/constant/zhuojiGameConstant");
let CardDown = require("../../mahjong/domain/cardDown");

let Player = function (cfg, frontendId, sessionId) {
    BasePlayer.call(this, cfg, frontendId, sessionId);
    this.cardsInHand = [];          //手牌
    this.cardsBefore = [];          //打出去的牌
    this.cardsDown = [];            //碰杠的牌
    this.cardGrab = 0;
    this.grabReason = 1;
    this.moCardNum = 0;
    this.chuPaiNum = 0;
    this.gangList = [];
    this.tingList = [];

    this.onclickTing = false;       //点听
    this.onclickTingChuPai = false; //点听后出牌(出完牌才算听)
    this.tingType = 0;              //1硬报,2软报
    this.tingChuType = 0;           //1硬报,2软报

    this.autoOperation = 0;         //0手动,1自动

    this.cancelHuList = [];         //过胡的牌
    this.cancelPengList = [];       //过碰的牌

    this.opStartTime = 0;
    this.errorTime = 0;
};

util.inherits(Player, BasePlayer);


//碰，明杠
Player.prototype.addCardDown = function (card, type, chuUid) {
    let cards = [];
    if(ZhuojiGameConstant.MAHJONG_OPERTAION_PENG === type) {
        cards = [card, card, card];
    } else if(ZhuojiGameConstant.MAHJONG_OPERTAION_AN_GANG === type
        || ZhuojiGameConstant.MAHJONG_OPERTAION_MING_GANG === type
        || ZhuojiGameConstant.MAHJONG_OPERTAION_BU_GANG === type) {
        cards = [card, card, card, card];
    }
    let cardDown = new CardDown();
    cardDown.type = type;
    cardDown.cards = cards;
    cardDown.chuPlayerUid = chuUid;
    this.cardsDown.push(cardDown);
    return cardDown;
};

//暗杠
Player.prototype.addGangCardDown = function (card, type, chuPlayer) {
    let cardDown = new CardDown();
    cardDown.cards = [card, card, card, card];
    cardDown.type = type;
    cardDown.chuPlayerUid = chuPlayer.getUid();
    for(let gang of this.gangList) {
        if(gang.cards[0] === card) {
            cardDown.isHanBaoDou = gang.isHanBaoDou;
            break;
        }
    }
    this.cardsDown.push(cardDown);
    return cardDown;
};

//补杠
Player.prototype.buGang = function (card) {
    for(let cardDown of this.cardsDown) {
        if(cardDown.type === ZhuojiGameConstant.MAHJONG_OPERTAION_PENG && cardDown.cards[0] === card) {
            cardDown.type = ZhuojiGameConstant.MAHJONG_OPERTAION_BU_GANG;
            cardDown.cards.push(card);
            cardDown.chuPlayerUid = this.getUid();
            for(let gang of this.gangList) {
                if(gang.cards[0] === card) {
                    cardDown.isHanBaoDou = gang.isHanBaoDou;
                    break;
                }
            }
            return;
        }
    }
};

Player.prototype.addCardBefore = function (card) {
    this.cardsBefore.push(card);
};

Player.prototype.clearCardGrab = function () {
    this.cardGrab = 0;
    this.grabReason = 1;
};

Player.prototype.setCardGrab = function (cardGrab, grabReason) {
    this.cardGrab = cardGrab;
    this.grabReason = grabReason;
};

Player.prototype.getCardGrab = function () {
    return this.cardGrab;
};

Player.prototype.countCardInBefore = function (card) {
    let numOfCards = 0;
    for (let c of this.cardsBefore) {
        if (c === card) {
            numOfCards ++;
        }
    }
    return numOfCards;
};

Player.prototype.countCardInDown = function (card) {
    for(let down of this.cardsDown) {
        if(down.type == ZhuojiGameConstant.MAHJONG_OPERTAION_PENG && down.cards[0] === card) {
            return 3;
        } else if ((down.type === ZhuojiGameConstant.MAHJONG_OPERTAION_AN_GANG
            || down.type === ZhuojiGameConstant.MAHJONG_OPERTAION_MING_GANG
            || down.type === ZhuojiGameConstant.MAHJONG_OPERTAION_BU_GANG)
            && down.cards[0] === card) {
            return 4;
        }
    }
    return 0;
};

Player.prototype.countCardInHand = function (card) {
    let numOfCards = 0;
    for (let c of this.cardsInHand) {
        if (c === card) {
            numOfCards ++;
        }
    }
    if (this.cardGrab !== 0 && this.cardGrab === card) {
        numOfCards ++;
    }
    return numOfCards;
};

Player.prototype.getXCardNumInHand = function (card) {
    let numOfCard = 0;
    for (let c of this.cardsInHand) {
        if (c === card) {
            numOfCard ++;
        }
    }
    return numOfCard;
};

Player.prototype.addCardInHand = function (card) {
    this.cardsInHand.push(card);
    this.sortCardInHand();
};

Player.prototype.hasCardInHand = function (card) {
    if (this.cardGrab !== 0 && this.cardGrab === card) {
        return true;
    }
    for(let cardInHand of this.cardsInHand) {
        if(cardInHand === card) {
            return true;
        }
    }
    return false;
};

Player.prototype.removeCardInHand = function (card) {
    if (card === 0){
        return 0;
    }
    for (let i = 0; i < this.cardsInHand.length; i++) {
        if (this.cardsInHand[i] === card) {
            this.cardsInHand.splice(i, 1);
            return card;
        }
    }
};

Player.prototype.sortCardInHand = function () {
    this.cardsInHand.sort((card1, card2) => card1 - card2);
};

Player.prototype.clearLastCancelHuCard = function () {
    this.cancelHuList = [];
};

Player.prototype.addLastCancelHuCard = function (cancelHuCard) {
    this.cancelHuList.push(cancelHuCard);
};

Player.prototype.haveCancelHuCard = function (card) {
    for(let cancelHuCard of this.cancelHuList) {
        if(cancelHuCard === card) {
            return true;
        }
    }
    return false;
};

Player.prototype.clearLastCancelPengCard = function () {
    this.cancelPengList = [];
};

Player.prototype.addLastCancelPengCard = function (cancelPengCard) {
    this.cancelPengList.push(cancelPengCard);
};

Player.prototype.haveCancelPengCards = function (card) {
    for(let cancelPengCard of this.cancelPengList) {
        if(cancelPengCard === card) {
            return true;
        }
    }
    return false;
};



Player.prototype.getCard = function (index) {
    return index < 0 || index >= this.cardsInHand.length ? 0 : this.cardsInHand[index];
};

Player.prototype.getAutoChuCard = function () {
    return this.cardGrab != 0 ? this.cardGrab : this.cardsInHand[0];
};


//checkGang的时候，获取cardsInHand中的暗杠；已经出过牌，暗杠是憨包豆
Player.prototype.getAnGangList = function () {
    let gangList = [];
    let cards = new Map();
    for(let card of this.cardsInHand) {
        if(cards.has(card)) {
            cards.set(card, cards.get(card) + 1);
        } else {
            cards.set(card, 1);
        }
        if(cards.get(card) == 4) {
            let cardDown = new CardDown();
            cardDown.type = ZhuojiGameConstant.MAHJONG_OPERTAION_AN_GANG;
            cardDown.cards = [card, card, card, card];
            cardDown.chuPlayerUid = this.getUid();
            cardDown.isHanBaoDou = this.chuPaiNum !== 0 ? 1 : 0;
            gangList.push(cardDown);
        }
    }
    return gangList;
};

Player.prototype.hasDou = function () {
    for (let down of this.cardsDown) {
        if (down.type == ZhuojiGameConstant.MAHJONG_OPERTAION_AN_GANG
            || down.type == ZhuojiGameConstant.MAHJONG_OPERTAION_MING_GANG
            || down.type == ZhuojiGameConstant.MAHJONG_OPERTAION_BU_GANG) {
            return true;
        }
    }
    return false;
};

Player.prototype.hasPeng = function (card) {
    for (let down of this.cardsDown) {
        if (down.type == ZhuojiGameConstant.MAHJONG_OPERTAION_PENG && down.cards[0] === card) {
            return true;
        }
    }
    return false;
};

Player.prototype.setTingTypeWhileOpTing = function (dealerUid) {
    if(this.uid === dealerUid && this.moCardNum <= 1 && this.chuPaiNum === 0 && this.cardsDown.length === 0) {
        this.tingType = 1;
    } else if (this.moCardNum === 1 && this.chuPaiNum === 0 && this.cardsDown.length === 0) {
        this.tingType = 2;
    } else {
        this.tingType = 0;
    }
};

Player.prototype.cardsInHandToString = function () {
    let s = '';
    for(let card of this.cardsInHand) {
        s += '0x' + card.toString(16) + ' ';
    }
    return s;
};

Player.prototype.cardsDownToString = function () {
    let s = '';
    for(let cardDown of this.cardsDown) {
        if(cardDown.type === ZhuojiGameConstant.MAHJONG_OPERTAION_PENG) {
            s += '0x' + cardDown.cards[0].toString(16) + '_0x' + cardDown.cards[1].toString(16) + '_0x' + cardDown.cards[2].toString(16) + ' ';
        } else if(cardDown.type === ZhuojiGameConstant.MAHJONG_OPERTAION_AN_GANG) {
            s += '0x' + cardDown.cards[0].toString(16) + '_0x' + cardDown.cards[1].toString(16) + '_0x' + cardDown.cards[2].toString(16) + '_0x' + cardDown.cards[3].toString(16) +  '_AN ';
        } else if(cardDown.type === ZhuojiGameConstant.MAHJONG_OPERTAION_MING_GANG) {
            s += '0x' + cardDown.cards[0].toString(16) + '_0x' + cardDown.cards[1].toString(16) + '_0x' + cardDown.cards[2].toString(16) + '_0x' + cardDown.cards[3].toString(16) +  '_MING ';
        } else if(cardDown.type === ZhuojiGameConstant.MAHJONG_OPERTAION_BU_GANG) {
            s += '0x' + cardDown.cards[0].toString(16) + '_0x' + cardDown.cards[1].toString(16) + '_0x' + cardDown.cards[2].toString(16) + '_0x' + cardDown.cards[3].toString(16) +  '_BU ';
        }
    }
    return s;
};


Player.prototype.calculateHuType = function (card) {
    return MahjongUtils.calculateHuType([...this.cardsInHand], [...this.cardsDown], card);
};


Player.prototype.resetInTable = function () {
    this.cardsInHand = [];
    this.cardsBefore = [];
    this.cardsDown = [];
    this.cardGrab = 0;
    this.grabReason = 1;
    this.moCardNum = 0;
    this.chuPaiNum = 0;
    this.gangList = [];
    this.tingList = [];
    this.onclickTing = false;       //点听
    this.onclickTingChuPai = false; //点听后出牌(出完牌才算听)
    this.tingType = 0;              //1硬报,2软报
    this.tingChuType = 0;           //1硬报,2软报
    this.autoOperation = 0;         //0手动,1自动
    this.cancelHuList = [];         //过胡的牌
    this.cancelPengList = [];       //过碰的牌
    this.opStartTime = 0;             //玩家可以操作计时
    this.errorTime = 0;
};


Player.prototype.toJSON = function () {
    return {
        account: this.account,
        position: this.position,
        balance: this.balance,
        isOnline: this.onlineFlag,
        readyFlag: this.readyFlag,
        cardsBefore: this.cardsBefore,
        cardsDown: this.cardsDown,
        cardsInHandNum: this.cardsInHand.length + (this.cardGrab === 0 ? 0 : 1),
        tingChuType: this.tingChuType
    };
};

exports.create = function (cfg, frontendId, sessionId) {
    let player = new Player(cfg, frontendId, sessionId);
    player.resetInTable();
    return player;
};